package com.ego.seckill.interceptor;

import com.ego.seckill.access.AccessLimit;
import org.springframework.web.method.HandlerMethod;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

/**
 * @author Ares
 * @date 2020-12-17
 */
@Component
public class AccessInterceptor implements HandlerInterceptor {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断是否需要限流
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod)handler;
            AccessLimit methodAnnotation = handlerMethod.getMethodAnnotation(AccessLimit.class);
            if (methodAnnotation == null) {
                return true;
            }
            int count = methodAnnotation.count();
            int seconds = methodAnnotation.seconds();

            //获取用户ip

            String remoteAddr = request.getRemoteAddr();
            String redisCount = stringRedisTemplate.opsForValue().get(remoteAddr);
            if (redisCount == null) {
                //说明是第一次访问
                stringRedisTemplate.opsForValue().set(remoteAddr, "1", seconds, TimeUnit.SECONDS);
            } else if(Integer.valueOf(redisCount) < count){
                stringRedisTemplate.opsForValue().increment(remoteAddr, 1);
            }else {
                response.setContentType("text/html;charset=utf-8");
                response.setStatus(401);
                PrintWriter writer = response.getWriter();
                writer.println("访问太频繁:" + seconds + "内最多访问:" + count + "次");
                writer.flush();
                return false;
            }

        }
        //根据ip进行限流
        return true;
    }


}
